home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / apache / bin / apxs.pl < prev    next >
Perl Script  |  2005-05-30  |  25KB  |  797 lines

  1. #!C:\xampp\perl\bin\perl.EXE -w
  2. # ====================================================================
  3. #
  4. #  Copyright 2003-2004  The Apache Software Foundation
  5. #
  6. #  Licensed under the Apache License, Version 2.0 (the "License");
  7. #  you may not use this file except in compliance with the License.
  8. #  You may obtain a copy of the License at
  9. #
  10. #      http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. #  Unless required by applicable law or agreed to in writing, software
  13. #  distributed under the License is distributed on an "AS IS" BASIS,
  14. #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. #  See the License for the specific language governing permissions and
  16. #  limitations under the License.
  17.  
  18. # apxs script designed to allow easy command line access to Apache
  19. # configuration parameters.
  20.  
  21. require 5.003;
  22. use strict;
  23. package apxs;
  24. use File::Copy;
  25. use File::Spec::Functions;
  26.  
  27. ##
  28. ##  Configuration
  29. ##
  30.  
  31. my %config_vars = ();
  32.  
  33. my $installbuilddir = 'O:\apache\build';
  34. get_config_vars("$installbuilddir/config_vars.mk",\%config_vars);
  35.  
  36. # read the configuration variables once
  37.  
  38. my $prefix          = get_vars('prefix');
  39. my $CFG_PREFIX      = $prefix;
  40. my $exec_prefix     = get_vars('exec_prefix');
  41. my $datadir         = get_vars('datadir');
  42. my $localstatedir   = get_vars('localstatedir');
  43. my $CFG_TARGET      = get_vars('progname');
  44. my $CFG_SYSCONFDIR  = get_vars('sysconfdir');
  45. my $CFG_SYSCONF     = get_vars('sysconf');
  46. my $CFG_CFLAGS      = join ' ', map { get_vars($_) }
  47.     qw(SHLTCFLAGS CFLAGS NOTEST_CPPFLAGS EXTRA_CPPFLAGS EXTRA_CFLAGS);
  48. my $includedir      = get_vars('includedir');
  49. my $CFG_INCLUDEDIR  = $includedir;
  50. my $libdir          = get_vars('libdir');
  51. my $CFG_LIBDIR      = $libdir;
  52. my $CFG_CC          = get_vars('CC');
  53. my $CFG_LD          = get_vars('LD');
  54. my $CFG_LDFLAGS     = get_vars('LDFLAGS');
  55. my $libexecdir      = get_vars('libexecdir');
  56. my $CFG_LIBEXECDIR  = $libexecdir;
  57. my $sbindir         = get_vars('sbindir');
  58. my $CFG_SBINDIR     = $sbindir;
  59. my $ltflags         = $ENV{LTFLAGS};
  60. my $apr_libname     = get_vars('APR_LIBNAME');
  61. my $aprutil_libname = get_vars('APRUTIL_LIBNAME');
  62.  
  63. $ltflags or $ltflags = '--silent';
  64.  
  65. my %internal_vars = map {$_ => 1}
  66.     qw(TARGET CC CFLAGS CFLAGS_SHLIB LD_SHLIB LDFLAGS_SHLIB LIBS_SHLIB
  67.        PREFIX SBINDIR INCLUDEDIR LIBEXECDIR SYSCONFDIR SYSCONF);
  68.  
  69. my $CP    = 'C:\xampp\perl\bin\perl.EXE -MExtUtils::Command -e cp';
  70. my $CHMOD = 'C:\xampp\perl\bin\perl.EXE -MExtUtils::Command -e chmod';
  71. my $RM_F  = 'C:\xampp\perl\bin\perl.EXE -MExtUtils::Command -e rm_f';
  72. my $TOUCH = 'C:\xampp\perl\bin\perl.EXE -MExtUtils::Command -e touch';
  73.  
  74. ##
  75. ##  parse argument line
  76. ##
  77.  
  78. #   defaults for parameters
  79. my $opt_n = '';
  80. my $opt_g = '';
  81. my $opt_c = 0;
  82. my $opt_o = '';
  83. my @opt_D = ();
  84. my @opt_I = ();
  85. my @opt_L = ();
  86. my @opt_l = ();
  87. my @opt_W = ();
  88. my @opt_S = ();
  89. my $opt_e = 0;
  90. my $opt_i = 0;
  91. my $opt_a = 0;
  92. my $opt_A = 0;
  93. my $opt_q = 0;
  94. my $opt_h = 0;
  95. my $opt_p = 0;
  96. my $opt_d = 0;
  97.  
  98. #   this subroutine is derived from Perl's getopts.pl with the enhancement of
  99. #   the "+" metacharacter at the format string to allow a list to be built by
  100. #   subsequent occurrences of the same option.
  101. sub Getopts {
  102.     my ($argumentative, @ARGV) = @_;
  103.     my $errs = 0;
  104.     local $_;
  105.     local $[ = 0;
  106.  
  107.     my @args = split / */, $argumentative;
  108.     while (@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) {
  109.         my ($first, $rest) = ($1,$2);
  110.         if ($_ =~ m|^--$|) {
  111.             shift @ARGV;
  112.             last;
  113.         }
  114.         my $pos = index($argumentative,$first);
  115.         if ($pos >= $[) {
  116.             if ($pos < $#args && $args[$pos+1] eq ':') {
  117.                 shift @ARGV;
  118.                 if ($rest eq '') {
  119.                     unless (@ARGV) {
  120.                         error("Incomplete option: $first (needs an argument)");
  121.                         $errs++;
  122.                     }
  123.                     $rest = shift(@ARGV);
  124.                 }
  125.                 eval "\$opt_$first = \$rest;";
  126.             }
  127.             elsif ($pos < $#args && $args[$pos+1] eq '+') {
  128.                 shift @ARGV;
  129.                 if ($rest eq '') {
  130.                     unless (@ARGV) {
  131.                         error("Incomplete option: $first (needs an argument)");
  132.                         $errs++;
  133.                     }
  134.                     $rest = shift(@ARGV);
  135.                 }
  136.                 eval "push(\@opt_$first, \$rest);";
  137.             }
  138.             else {
  139.                 eval "\$opt_$first = 1";
  140.                 if ($rest eq '') {
  141.                     shift(@ARGV);
  142.                 }
  143.                 else {
  144.                     $ARGV[0] = "-$rest";
  145.                 }
  146.             }
  147.         }
  148.         else {
  149.             error("Unknown option: $first");
  150.             $errs++;
  151.             if ($rest ne '') {
  152.                 $ARGV[0] = "-$rest";
  153.             }
  154.             else {
  155.                 shift(@ARGV);
  156.             }
  157.         }
  158.     }
  159.     return ($errs == 0, @ARGV);
  160. }
  161.  
  162. sub usage {
  163.     print STDERR <<'END';
  164. Usage: apxs -g [-S <var>=<val>] -n <modname>
  165.        apxs -q [-S <var>=<val>] <query> ...
  166.        apxs -c [-S <var>=<val>] [-o <dsofile>] [-D <name>[=<value>]]
  167.                [-I <incdir>] [-L <libdir>] [-l <libname>] [-Wc,<flags>]
  168.                [-Wl,<flags>] [-p] <files> ...
  169.        apxs -i [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...
  170.        apxs -e [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...
  171.  
  172. END
  173.     exit(1);
  174. }
  175.  
  176. #   option handling
  177. my $rc;
  178. ($rc, @ARGV) = &Getopts("qn:gco:I+D+L+l+W+S+eiaApd", @ARGV);
  179. &usage if ($rc == 0);
  180. &usage if ($#ARGV == -1 and not $opt_g);
  181. &usage if (not $opt_q and not ($opt_g and $opt_n) 
  182.            and not $opt_i and not $opt_c and not $opt_e);
  183.  
  184. #   argument handling
  185. my @args = @ARGV;
  186. my $name = 'unknown';
  187. $name = $opt_n if ($opt_n ne '');
  188.  
  189. if (@opt_S) {
  190.     my ($opt_S);
  191.     foreach $opt_S (@opt_S) {
  192.         if ($opt_S =~ m/^([^=]+)=(.*)$/) {
  193.             my ($var) = $1;
  194.             my ($val) = $2;
  195.             my $oldval = eval "\$CFG_$var";
  196.  
  197.             unless ($var and $oldval) {
  198.                 print STDERR "apxs:Error: no config variable $var\n";
  199.                 &usage;
  200.             }
  201.  
  202.             eval "\$CFG_${var}=\"${val}\"";
  203.         } else {
  204.             print STDERR "apxs:Error: malformatted -S option\n";
  205.             &usage;
  206.         }    
  207.     }
  208. }
  209.  
  210. ##
  211. ##  Initial shared object support check
  212. ##
  213. my $httpd = catfile get_vars("sbindir"), get_vars("progname");
  214. my $envvars = catfile get_vars("sbindir"), "envvars";
  215.  
  216. #allow apxs to be run from the source tree, before installation
  217. if ($0 =~ m:support/apxs$:) {
  218.     ($httpd = $0) =~ s:support/apxs$::;
  219. }
  220.  
  221. unless (-f $httpd) {
  222.     error("$httpd not found or not executable");
  223.     exit 1;
  224. }
  225.  
  226. sub get_config_vars{
  227.     my ($file, $rh_config) = @_;
  228.  
  229.     open IN, $file or die "cannot open $file: $!";
  230.     while (<IN>){
  231.         if (/^\s*(.*?)\s*=\s*(.*)$/){
  232.             $rh_config->{$1} = $2;
  233.         }
  234.     }
  235.     close IN;
  236. }
  237.  
  238. sub get_vars {
  239.     my $result = '';
  240.     my $ok = 0;
  241.     my $arg;
  242.     foreach $arg (@_) {
  243.         if (exists $config_vars{$arg} or exists $config_vars{lc $arg}) {
  244.             my $val = exists $config_vars{$arg}
  245.                 ? $config_vars{$arg}
  246.                     : $config_vars{lc $arg};
  247.             $val =~ s/[()]//g;
  248.             $result .= $val if defined $val;
  249.             $result .= ";;"; 
  250.             $ok = 1;
  251.         }
  252.         if (not $ok) {
  253.             if (exists $internal_vars{$arg} 
  254.                 or exists $internal_vars{lc $arg}) {
  255.                 my $val = exists $internal_vars{$arg} ? $arg : lc $arg;
  256.                 $val = eval "\$CFG_$val";
  257.                 $result .= $val if defined $val;
  258.                 $result .= ";;";
  259.                 $ok = 1;
  260.             }
  261.             if (not $ok) {
  262.                 error("Invalid query string `$arg'");
  263.                 exit(1);
  264.             }
  265.         }
  266.     }
  267.     $result =~ s|;;$||;
  268.     #    $result =~ s|:| |;
  269.     return $result;
  270. }
  271.  
  272. ##
  273. ##  Operation
  274. ##
  275.  
  276. #   helper function for executing a list of
  277. #   system command with return code checks
  278. sub execute_cmds {
  279.     my (@cmds) = @_;
  280.     my ($cmd, $rc);
  281.  
  282.     foreach $cmd (@cmds) {
  283.         notice($cmd);
  284.         $rc = system $cmd;
  285.         if ($rc) {
  286.             error(sprintf "Command failed with rc=%d\n", $rc << 8);
  287.             exit 1 ;
  288.         }
  289.     }
  290. }
  291.  
  292. if ($opt_g) {
  293.     ##
  294.     ##  SAMPLE MODULE SOURCE GENERATION
  295.     ##
  296.  
  297.     if (-d $name) {
  298.         error("Directory `$name' already exists. Remove first");
  299.         exit(1);
  300.     }
  301.  
  302.     my $data = join('', <DATA>);
  303.     $data =~ s!__END__.*!!s;
  304.     $data =~ s|%NAME%|$name|sg;
  305.     $data =~ s|%SYSCONF%|$CFG_SYSCONF|sg;
  306.     $data =~ s|%PREFIX%|$prefix|sg;
  307.     $data =~ s|%INSTALLBUILDDIR%|$installbuilddir|sg;
  308.  
  309.     my ($mkf, $src) = ($data =~ m|^(.+)-=\#=-\n(.+)|s);
  310.  
  311.     notice("Creating [DIR]  $name");
  312.     mkdir $name or die "Cannot mkdir $name: $!";
  313.     notice("Creating [FILE] $name/Makefile");
  314.     open(FP, ">${name}/Makefile") or die "Cannot open ${name}/Makefile: $!";
  315.     print FP $mkf;
  316.     close(FP);
  317.     notice("Creating [FILE] $name/mod_$name.c");
  318.     open(FP, ">${name}/mod_${name}.c") || die;
  319.     print FP $src;
  320.     close(FP);
  321.     notice("Creating [FILE] $name/.deps");
  322.     open(FP, ">${name}/.deps") or die "Cannot open ${name}/.deps: $!";
  323.     close(FP);
  324.  
  325.     exit(0);
  326. }
  327.  
  328. if ($opt_q) {
  329.     ##
  330.     ##  QUERY INFORMATION 
  331.     ##
  332.     my $result = get_vars(@args);
  333.     print "$result\n";
  334. }
  335.  
  336. my $apr_bindir = get_vars("APR_BINDIR");
  337. my $apu_bindir = get_vars("APU_BINDIR");
  338.  
  339. my $apr_includedir = qq{-I"$prefix/include"};
  340. my $apu_includedir = qq{-I$"prefix/include"};
  341.  
  342. if ($opt_c) {
  343.     ##
  344.     ##  SHARED OBJECT COMPILATION
  345.     ##
  346.     
  347.     #   split files into sources and objects
  348.     my @srcs = ();
  349.     my @objs = ();
  350.     my $f;
  351.     foreach $f (@args) {
  352.         if ($f =~ m|\.c$|) {
  353.             push(@srcs, $f);
  354.         }
  355.         else {
  356.             push(@objs, $f);
  357.         }
  358.     }
  359.  
  360.     #   determine output file
  361.     my $dso_file;
  362.     if ($opt_o eq '') {
  363.         if ($#srcs > -1) {
  364.             $dso_file = $srcs[0];
  365.             $dso_file =~ s|\.[^.]+$|.so|;
  366.         }
  367.         elsif ($#objs > -1) {
  368.             $dso_file = $objs[0];
  369.             $dso_file =~ s|\.[^.]+$|.so|;
  370.         }
  371.         else {
  372.             $dso_file = "mod_unknown.so";
  373.         }
  374.     }
  375.     else {
  376.         $dso_file = $opt_o;
  377.     }
  378.  
  379.     #   create compilation commands
  380.     my @cmds = ();
  381.     my $opt = '';
  382.     my ($opt_Wc, $opt_I, $opt_D);
  383.     foreach $opt_Wc (@opt_W) {
  384.         $opt .= "$1 " if ($opt_Wc =~ m|^\s*c,(.*)$|);
  385.     }
  386.     foreach $opt_I (@opt_I) {
  387.         $opt .= qq{ /I"$opt_I" };
  388.     }
  389.     foreach $opt_D (@opt_D) {
  390.         $opt .= qq{ /D "$opt_D" };
  391.     }
  392.     my $cflags = "$CFG_CFLAGS";
  393.     if ($opt_d) {
  394.         $cflags =~ s!NDEBUG!DEBUG!;
  395.         $cflags .= ' /Zi';
  396.         $cflags =~ s!/MD !/MDd !;
  397.     }
  398.     my $s;
  399.     my $mod;
  400.     foreach $s (@srcs) {
  401.         my $slo = $s;
  402.         $slo =~ s|\.c$|.slo|;
  403.         my $lo = $s;
  404.         $lo =~ s|\.c$|.lo|;
  405.         my $la = $s;
  406.         $la =~ s|\.c$|.la|;
  407.         my $o = $s;
  408.         $o =~ s|\.c$|.o|;
  409.         push(@cmds, qq{$CFG_CC $cflags -I"$CFG_INCLUDEDIR" $opt /c /Fo$lo $s});
  410.         unshift(@objs, $lo);
  411.     }
  412.  
  413.     #   create link command
  414.     my $o;
  415.     my $lo;
  416.     $opt = '';
  417.     foreach $o (@objs) {
  418.         $lo .= " $o";
  419.     }
  420.     my ($opt_Wl, $opt_L, $opt_l);
  421.     foreach $opt_Wl (@opt_W) {
  422.         if ($CFG_CC !~ m/gcc$/) {
  423.             $opt .= " $1" if ($opt_Wl =~ m|^\s*l,(.*)$|);
  424.         } else {
  425.             $opt .= " -W$opt_Wl";
  426.         }
  427.     }
  428.     foreach $opt_L (@opt_L) {
  429.         $opt .= qq{ /libpath:"$opt_L" };
  430.     }
  431.     foreach $opt_l (@opt_l) {
  432.         $opt_l .= '.lib' unless ($opt_l =~ /\.lib$/); 
  433.         $opt .= " $opt_l";
  434.     }
  435.  
  436.     if ($opt_p == 1) {
  437.         $opt .= " ".$aprutil_libname." ".$apr_libname;
  438.     }
  439.     else {
  440.         my $apr_ldflags;
  441.         $opt .= " $apr_ldflags";
  442.     }
  443.     my $ldflags = "$CFG_LDFLAGS";
  444.     if ($opt_d) {
  445.         $ldflags .= ' /debug';
  446.     }
  447.     push(@cmds, "$CFG_LD $ldflags /out:$dso_file $opt $lo");
  448.  
  449.     #   execute the commands
  450.     &execute_cmds(@cmds);
  451.  
  452.     #   allow one-step compilation and installation
  453.     if ($opt_i or $opt_e) {
  454.         @args = ( $dso_file );
  455.     }
  456. }
  457.  
  458. if ($opt_i or $opt_e) {
  459.     ##
  460.     ##  SHARED OBJECT INSTALLATION
  461.     ##
  462.     unless (-d $CFG_LIBEXECDIR) {
  463.         die "Directory $CFG_LIBEXECDIR not found";
  464.     }
  465.     #   determine installation commands
  466.     #   and corresponding LoadModule/AddModule directives
  467.     my @lmd = ();
  468.     my @amd = ();
  469.     my @cmds = ();
  470.     my $f;
  471.     foreach $f (@args) {
  472.         my $end = qr{(\.so|\.la)$};
  473.         if ($f !~ m!$end!) {
  474.             error("file $f is not a shared object");
  475.             exit(1);
  476.         }
  477.         my $t = $f;
  478.         $t =~ s|^.+/([^/]+)$|$1|;
  479.         $t =~ s|\.la$|\.so|;
  480.         (my $libf = $f) =~ s!$end!.lib!;
  481.         (my $libt = $t) =~ s!$end!.lib!;
  482.         (my $pdbf = $f) =~ s!$end!.pdb!;
  483.         (my $pdbt = $t) =~ s!$end!.pdb!;
  484.  
  485.         if ($opt_i) {
  486.             push(@cmds, "$CP $f $CFG_LIBEXECDIR");
  487.             push(@cmds, "$CHMOD 755 $CFG_LIBEXECDIR\\$t");
  488.             if (-f $libf) {
  489.                 push(@cmds, "$CP $libf $CFG_LIBDIR");
  490.                 push(@cmds, "$CHMOD 755 $CFG_LIBDIR\\$libt");
  491.             }
  492.             if ($opt_d and -f $pdbf) {
  493.                 push(@cmds, "$CP $pdbf $CFG_LIBEXECDIR");
  494.                 push(@cmds, "$CHMOD 755 $CFG_LIBEXECDIR\\$pdbt");
  495.             }
  496.         }
  497.  
  498.         #   determine module symbolname and filename
  499.         my $filename = '';
  500.         if ($name eq 'unknown') {
  501.             $name = '';
  502.             my $base = $f;
  503.             $base =~ s|\.[^.]+$||;
  504.             if (-f "$base.c") {
  505.                 open(FP, "<$base.c");
  506.                 my $content = join('', <FP>);
  507.                 close(FP);
  508.                 if ($content =~ m|.*module\s+(?:AP_MODULE_DECLARE_DATA\s+)?([a-zA-Z0-9_]+)_module\s*=\s*.*|s) {
  509.                     $name = "$1";
  510.                     $filename = "$base.c";
  511.                     $filename =~ s|^[^/]+/||;
  512.                 }
  513.             }
  514.             if ($name eq '') {
  515.                 if ($base =~ m|.*mod_([a-zA-Z0-9_]+)\..+|) {
  516.                     $name = "$1";
  517.                     $filename = $base;
  518.                     $filename =~ s|^[^/]+/||;
  519.                 }
  520.             }
  521.             if ($name eq '') {
  522.                 error("Sorry, cannot determine bootstrap symbol name");
  523.                 error("Please specify one with option `-n'");
  524.                 exit(1);
  525.             }
  526.         }
  527.         if ($filename eq '') {
  528.             $filename = "mod_${name}.c";
  529.         }
  530.         my $dir = $CFG_LIBEXECDIR;
  531.         $dir =~ s|^$CFG_PREFIX/?||;
  532.         $dir =~ s|(.)$|$1/|;
  533.         $dir =~ s|\\|/|g;
  534.         $t =~ s|\.la$|.so|;
  535.         push(@lmd, 
  536.              sprintf("LoadModule %-18s %s", "${name}_module", qq{"$dir$t"}));
  537.         push(@amd, sprintf("AddModule %s", $filename));
  538.     }
  539.  
  540.     #   execute the commands
  541.     &execute_cmds(@cmds);
  542.  
  543.     #   activate module via LoadModule/AddModule directive
  544.     if ($opt_a or $opt_A) {
  545.         if (not -f "$CFG_SYSCONFDIR/$CFG_SYSCONF") {
  546.             error("Config file $CFG_SYSCONFDIR/$CFG_SYSCONF not found");
  547.             exit(1);
  548.         }
  549.  
  550.         open(FP, "<$CFG_SYSCONFDIR/$CFG_SYSCONF") 
  551.             || die "Cannot open $CFG_SYSCONFDIR/$CFG_SYSCONF: $!";
  552.         my $content = join('', <FP>);
  553.         close(FP);
  554.  
  555.         if ($content !~ m|\n\#?\s*LoadModule\s+|) {
  556.             error("Activation failed for custom $CFG_SYSCONFDIR/$CFG_SYSCONF file.");
  557.             error("At least one `LoadModule' directive already has to exist.");
  558.             exit(1);
  559.         }
  560.  
  561.         my $lmd;
  562.         my $c = '';
  563.         $c = '#' if ($opt_A);
  564.         foreach $lmd (@lmd) {
  565.             my $what = $opt_A ? "preparing" : "activating";
  566.             if ($content !~ m|\n\#?\s*$lmd|) {
  567.                 # check for open <containers>, so that the new LoadModule
  568.                 # directive always appears *outside* of an <container>.
  569.  
  570.                 my $before = 
  571.                     ($content =~ m|^(.*\n)\#?\s*LoadModule\s+[^\n]+\n|s)[0];
  572.  
  573.                 # the '()=' trick forces list context and the scalar
  574.                 # assignment counts the number of list members (aka number
  575.                 # of matches) then
  576.                 my $cntopen = () = ($before =~ m|^\s*<[^/].*$|mg);
  577.                 my $cntclose = () = ($before =~ m|^\s*</.*$|mg);
  578.  
  579.                 if ($cntopen == $cntclose) {
  580.                     # fine. Last LoadModule is contextless.
  581.                     $content =~ s|^(.*\n\#?\s*LoadModule\s+[^\n]+\n)|$1$c$lmd\n|s;
  582.                 }
  583.                 elsif ($cntopen < $cntclose) {
  584.                     error('Configuration file is not valid. There are sections'
  585.                           . ' closed before opened.');
  586.                     exit(1);
  587.                 }
  588.                 else {
  589.                     # put our cmd after the section containing the last
  590.                     # LoadModule.
  591.                     my $found =
  592.                         $content =~ s!\A (  # string and capture start
  593.                                           (?:(?:
  594.                                               ^\s*  # start of conf line with a
  595.                                               (?:[^<]|<[^/]) # directive which
  596.                                                              # does not
  597.                                                              # start with '</'
  598.                                               
  599.                                               .*(?:$)\n  # rest of the line.
  600.                                                  # the '$' is in parentheses
  601.                                                  # to avoid misinterpreting
  602.                                                  # the string "$\" as
  603.                                                  # perl variable.
  604.                                                  
  605.                                                 )* # catch as much as possible
  606.                                                    # of such lines. (including
  607.                                                    # zero)
  608.                                               
  609.                                               ^\s*</.*(?:$)\n? 
  610.                                                    # after the above, we
  611.                                                    # expect a config line with
  612.                                                    # a closing container (</)
  613.                                                        
  614.                                                       ) {$cntopen}       
  615.                                               # the whole pattern (bunch
  616.                                               # of lines that end up with
  617.                                               # a closing directive) must
  618.                                               # be repeated $cntopen
  619.                                               # times. That's it.
  620.                                               # Simple, eh? ;-)
  621.                                     
  622.                                              )  # capture end  
  623.                                            !$1$c$lmd\n!mx;  
  624.                     unless ($found) {
  625.                         error('Configuration file is not valid. There are '
  626.                               . 'sections opened and not closed.');
  627.                         exit(1);
  628.                     }
  629.                 }
  630.             }
  631.             else {
  632.                 # replace already existing LoadModule line
  633.                 $content =~ s|^(.*\n)\#?\s*$lmd[^\n]*\n|$1$c$lmd\n|s;
  634.             }
  635.             $lmd =~ m|LoadModule\s+(.+?)_module.*|;
  636.             notice("[$what module `$1' in $CFG_SYSCONFDIR\\$CFG_SYSCONF]");
  637.         } 
  638.         my $amd;
  639.         foreach $amd (@amd) {
  640.             if ($content !~ m|\n\#?\s*$amd|) {
  641.                 $content =~ s|^(.*\n\#?\s*AddModule\s+[^\n]+\n)|$1$c$amd\n|sg;
  642.             } 
  643.             else {
  644.                 $content =~ s|^(.*\n)\#?\s*$amd[^\n]*\n|$1$c$amd\n|sg;
  645.             }
  646.         }
  647.  
  648.         if (@lmd or @amd) {
  649.             my $conf = catfile $CFG_SYSCONFDIR, $CFG_SYSCONF;
  650.             my $conf_new = $conf . '.new';
  651.             my $conf_bak = $conf . '.bak';
  652.             if (open(FP, '>', $conf_new)) {
  653.                 print FP $content;
  654.                 close(FP);
  655.                 copy($conf, $conf_bak) or
  656.                          die "Backup of $conf failed: $!";
  657.                 copy($conf_new, $conf) or
  658.                          die "Copying $conf_new to $conf failed: $!";
  659.                 unlink $conf_new or
  660.                     die "Removing $conf_new failed: $!";
  661.             } 
  662.             else {
  663.                 notice("unable to open configuration file $conf_new");
  664.             }
  665.         }
  666.     }
  667. }
  668.  
  669. sub error{
  670.     print STDERR "apxs:Error: $_[0].\n";
  671. }
  672.  
  673. sub notice{
  674.     print STDERR "$_[0]\n";
  675. }
  676.  
  677. ##EOF##
  678. __DATA__
  679. ##
  680. ##  Makefile -- Build procedure for sample %NAME% Apache module
  681. ##  Autogenerated via ``apxs -n %NAME% -g''.
  682. ##
  683.  
  684. builddir=.
  685. top_srcdir=%PREFIX%
  686. top_builddir=%PREFIX%
  687.  
  688. #   the used tools
  689. APXS=apxs
  690. APACHECTL=Apache.exe -k
  691.  
  692. #   additional defines, includes and libraries
  693. #DEFS=-Dmy_define=my_value
  694. #INCLUDES=-Imy/include/dir
  695. #LIBS=-Lmy/lib/dir -lmylib
  696.  
  697. #   the default target
  698. all: local-shared-build
  699.  
  700. #   install the shared object file into Apache 
  701. install: install-modules
  702.  
  703. #   cleanup
  704. clean:
  705.         -@erase mod_%NAME%.lo mod_%NAME%.ilk mod_%NAME%.so mod_%NAME%.lib mod_%NAME%.exp mod_%NAME%.pdb
  706.  
  707. #   simple test
  708. test: reload
  709.     GET http://localhost/%NAME%
  710.  
  711. #   install and activate shared object by reloading Apache to
  712. #   force a reload of the shared object file
  713. reload: install restart
  714.  
  715. #   the general Apache start/restart/stop
  716. #   procedures
  717. start:
  718.     $(APACHECTL) start
  719. restart:
  720.     $(APACHECTL) restart
  721. stop:
  722.     $(APACHECTL) stop
  723.  
  724. -=#=-
  725. /* 
  726. **  mod_%NAME%.c -- Apache sample %NAME% module
  727. **  [Autogenerated via ``apxs -n %NAME% -g'']
  728. **
  729. **  To play with this sample module first compile it into a
  730. **  DSO file and install it into Apache's modules directory 
  731. **  by running:
  732. **
  733. **    $ apxs -c -i mod_%NAME%.c
  734. **
  735. **  Then activate it in Apache's %SYSCONF% file for instance
  736. **  for the URL /%NAME% in as follows:
  737. **
  738. **    #   %SYSCONF%
  739. **    LoadModule %NAME%_module modules/mod_%NAME%.so
  740. **    <Location /%NAME%>
  741. **    SetHandler %NAME%
  742. **    </Location>
  743. **
  744. **  Then after restarting Apache via
  745. **
  746. **    $ apachectl restart
  747. **
  748. **  you immediately can request the URL /%NAME% and watch for the
  749. **  output of this module. This can be achieved for instance via:
  750. **
  751. **    $ lynx -mime_header http://localhost/%NAME% 
  752. **
  753. **  The output should be similar to the following one:
  754. **
  755. **    HTTP/1.1 200 OK
  756. **    Date: Tue, 31 Mar 1998 14:42:22 GMT
  757. **    Server: Apache/1.3.4 (Unix)
  758. **    Connection: close
  759. **    Content-Type: text/html
  760. **  
  761. **    The sample page from mod_%NAME%.c
  762. */ 
  763.  
  764. #include "httpd.h"
  765. #include "http_config.h"
  766. #include "http_protocol.h"
  767. #include "ap_config.h"
  768.  
  769. /* The sample content handler */
  770. static int %NAME%_handler(request_rec *r)
  771. {
  772.     if (strcmp(r->handler, "%NAME%")) {
  773.         return DECLINED;
  774.     }
  775.     r->content_type = "text/html";      
  776.  
  777.     if (!r->header_only)
  778.         ap_rputs("The sample page from mod_%NAME%.c\n", r);
  779.     return OK;
  780. }
  781.  
  782. static void %NAME%_register_hooks(apr_pool_t *p)
  783. {
  784.     ap_hook_handler(%NAME%_handler, NULL, NULL, APR_HOOK_MIDDLE);
  785. }
  786.  
  787. /* Dispatch list for API hooks */
  788. module AP_MODULE_DECLARE_DATA %NAME%_module = {
  789.     STANDARD20_MODULE_STUFF, 
  790.     NULL,                  /* create per-dir    config structures */
  791.     NULL,                  /* merge  per-dir    config structures */
  792.     NULL,                  /* create per-server config structures */
  793.     NULL,                  /* merge  per-server config structures */
  794.     NULL,                  /* table of config file commands       */
  795.     %NAME%_register_hooks  /* register hooks                      */
  796. };
  797.